﻿using System;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;

using xEngine.Input;
using xEngine.Rendering;

namespace xEngine.UI.Screens
{
    public class ScreenText : Screen
    {
        #region Member Variables

        private String[] _text;
        private float _time;
        private SpriteFont _font;
        private Color _color;
        private bool _wrap;
        private TextAlign _align;

        #endregion

        #region Properties
        #endregion

        #region Constructors

        public ScreenText(String text, SpriteFont font, Color color, bool wrap, TextAlign align, float time, Keys? skipBtn) : base(skipBtn)
        {
            _font = font;
            _color = color;
            _wrap = wrap;
            _align = align;
            ProcessMouse = false;
            _text = text.Split(new string[] { "\\n", "\n" }, StringSplitOptions.None);
            _time = time;
        }

        #endregion

        #region Functions
        
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            _time -= (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (_time <= FadeTimeout)
                FadeOut();
        }
        public override void Render(GameTime gameTime)
        {
            ScreenManager.SpriteBatch.Begin();
            if (_wrap)
                RenderWrap();
            else
                RenderNormal();
            ScreenManager.SpriteBatch.End();

            base.Render(gameTime);
        }

        private void RenderNormal()
        {
            int offset = 5;
            int w = ScreenManager.GraphicsDevice.Viewport.Width;
            
            Vector2 m;

            float space = _font.MeasureString(" ").X * ScreenManager.DesignScale.X;

            foreach (String s in _text)
            {
                m = _font.MeasureString((s != "" ? s : "Tj"));

                switch (_align)
                {
                    case TextAlign.Center:
                        ScreenManager.SpriteBatch.DrawString(_font, s, new Vector2((w - m.X) / 2, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                        break;

                    case TextAlign.Left:
                        ScreenManager.SpriteBatch.DrawString(_font, s, new Vector2(10, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                        break;

                    case TextAlign.Right:
                        ScreenManager.SpriteBatch.DrawString(_font, s, new Vector2(w - m.X - 10, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                        break;

                    case TextAlign.Justify:
                        // Check if not too short
                        if (m.X > w * 0.7)
                        {
                            float remaining = w - m.X - 10;
                            int spaces = (int)(remaining / space);
                            int off = 0;
                            String ss = s;

                            for (int i = 0; i < spaces; i++)
                            {
                                int p = ss.IndexOf(' ', off);

                                if (p > 0)
                                {
                                    ss = ss.Insert(p, " ");
                                    off = p + 2;
                                }
                                else
                                {
                                    off = 0;
                                    p = ss.IndexOf(' ');

                                    if (p > 0)
                                    {
                                        ss = ss.Insert(p, " ");
                                        off = p + 2;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }

                            m = _font.MeasureString((s != "" ? s : "Tj")) * ScreenManager.DesignScale.ToVector2();
                            ScreenManager.SpriteBatch.DrawString(_font, ss, new Vector2((w - m.X) / 2, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                        }
                        else
                            ScreenManager.SpriteBatch.DrawString(_font, s, new Vector2((w - m.X) / 2, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                        break;
                }

                offset += (int)m.Y;
            }
        }
        private void RenderWrap()
        {
            int offset = 5;
            int w = ScreenManager.GraphicsDevice.Viewport.Width;
            int pos;

            float space = _font.MeasureString(" ").X * ScreenManager.DesignScale.X;

            String sub, rem;
            Vector2 m;   

            foreach (String s in _text)
            {
                rem = s;

                do
                {
                    sub = rem;
                    rem = "";

                    m = _font.MeasureString((sub != "" ? sub : "Tj")) * ScreenManager.DesignScale.ToVector2();

                    while (w < m.X + 20)
                    {
                        pos = sub.LastIndexOf(' ');

                        rem = sub.Substring(pos + 1) + (rem != "" ? " " : "") + rem;
                        sub = sub.Substring(0, pos);

                        m = _font.MeasureString((sub != "" ? sub : "Tj")) * ScreenManager.DesignScale.ToVector2();
                    }

                    switch (_align)
                    {
                        case TextAlign.Center:
                            ScreenManager.SpriteBatch.DrawString(_font, sub, new Vector2((w - m.X) / 2, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                            break;

                        case TextAlign.Left:
                            ScreenManager.SpriteBatch.DrawString(_font, sub, new Vector2(10, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                            break;

                        case TextAlign.Right:
                            ScreenManager.SpriteBatch.DrawString(_font, sub, new Vector2(w - m.X - 10, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                            break;

                        case TextAlign.Justify:
                            // Check if not too short
                            if (m.X > w * 0.7)
                            {
                                float remaining = w - m.X - 10;
                                int spaces = (int)(remaining / space);
                                int off = 0;

                                for (int i = 0; i < spaces; i++)
                                {
                                    int p = sub.IndexOf(' ', off);

                                    if (p > 0)
                                    {
                                        sub = sub.Insert(p, " ");
                                        off = p + 2;
                                    }
                                    else
                                    {
                                        off = 0;
                                        p = sub.IndexOf(' ');

                                        if (p > 0)
                                        {
                                            sub = sub.Insert(p, " ");
                                            off = p + 2;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }

                                m = _font.MeasureString((sub != "" ? sub : "Tj")) * ScreenManager.DesignScale.ToVector2();
                                ScreenManager.SpriteBatch.DrawString(_font, sub, new Vector2((w - m.X) / 2, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                            }
                            else
                                ScreenManager.SpriteBatch.DrawString(_font, sub, new Vector2((w - m.X) / 2, offset), _color, 0, Vector2.Zero, ScreenManager.DesignScale.ToVector2(), SpriteEffects.None, 0);
                            break;
                    }

                    offset += (int)m.Y;
                }
                while (rem != "");
            }
        }

        #endregion
    }

    public enum TextAlign
    {
        Left,
        Center,
        Right,
        Justify
    }
}
